home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c++ / 252 < prev    next >
Encoding:
Text File  |  1996-08-06  |  5.3 KB  |  152 lines

  1. Path: cs.mu.OZ.AU!bounce-back
  2. From: James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de>
  3. Newsgroups: comp.std.c++
  4. Subject: Re: Why no allocator-specific delete?
  5. Date: 03 Feb 96 04:56:43 GMT
  6. Organization: -
  7. Approved: fjh@cs.mu.oz.au
  8. Message-ID: <9602021056.AA05851@lts.sel.alcatel.de>
  9. References: <4dvid8$460@news.bridge.net> <4e0u1s$5fv@engnews1.Eng.Sun.COM> <4e85k6$b04@noc.tor.hookup.net> <KANZE.96Jan29095513@slsvewt.lts.sel.alcatel.de> <4eqn5b$les@noc.tor.hookup.net>
  10. NNTP-Posting-Host: munta.cs.mu.oz.au
  11. X-Original-Date: Fri, 2 Feb 96 11:56:12 +0100
  12. In-Reply-To: mtimmerm@microstar.com's message of 01 Feb 1996 09:26:44 PST
  13. X-Auth: PGPMoose V1.1 PGP comp.std.c++
  14.     iQBFAgUBMRLrOOEDnX0m9pzZAQFK6gF/R+VHDly6ZiRfqmQHiXTCuptA4bk8ykaa
  15.     XDAz9p/mWySwKfcBFZ0BS/sKfe62aIUQ
  16.     =9MGw
  17. Originator: fjh@munta.cs.mu.OZ.AU
  18.  
  19. In article <4eqn5b$les@noc.tor.hookup.net> mtimmerm@microstar.com
  20. (Matt Timmermans) writes:
  21.  
  22. |> (kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763))
  23.  
  24. |> |   In article <4e85k6$b04@noc.tor.hookup.net> mtimmerm@microstar.com
  25. |> |   (Matt Timmermans) writes:
  26. |> |
  27. |> |   |   ...  I can't, in fact, think of a single way that
  28. |> |   |   placement-new could be used properly.
  29. |> |
  30. |> |   [two decent uses described]
  31. |> |
  32. |> |   |   The lack of a placement-delete is on of the many factors in C++
  33. |> |   |   conspiring to make it absolutely impossible to make generic
  34. |> |   |   collections that hold actual objects (with constructors) instead
  35. |> |   |   of just pointers.
  36.  
  37. |> |   I don't understand the problem.  My containers all contain actual
  38. |> |   objects, and not just pointers.
  39.  
  40. |> I spoke somewhat too generally.  Let's say I want to make a generic list:
  41.  
  42. |> template <class T> class ListOf;
  43.  
  44. |> which stores acutal objects of type T (not just pointers) and contains
  45. |> methods to add and delete items from the list.  Lets say I also have a
  46. |> class:
  47.  
  48. |> class A
  49. |>     {
  50. |>     ...
  51. |>     public:
  52. |>     A(int alpha,int beta);
  53. |>     ~A();
  54. |>     };
  55.  
  56. |> Note that class A has no valid copy semantics.  How can I implement ListOf
  57. |> such that ListOf<int> and ListOf<A> both work?  There are lots of slimy
  58. |> hacks, but no elegant solutions.
  59.  
  60. You must provide ListOf with some way of knowing how to construct an
  61. object in the list.  STL takes the simple approach: a copy constructor
  62. will be used.  My own container classes will use either a copy
  63. constructor *or* the default constructor, according to the function
  64. invoked.  (In fact, not all of my container classes do this.)  In both
  65. cases, however, ListOf implicitly knows how to construct an object; if
  66. what ListOf implicitly knows isn't true, you're out of luck.
  67.  
  68. The alternative would be to provide a constructor functional object as
  69. parameter for all functions which might need to construct an object.
  70. This is totally general, but may be a pain for users in the vaste
  71. majority of cases where copying is the best solution.
  72.  
  73. Thus, in the list class itself:
  74.  
  75.     template< class T >
  76.     class ListOf
  77.     {
  78.     public :
  79.         class ElemCtor
  80.         {
  81.         public :
  82.             virtual             ~ElemCtor() {}
  83.             virtual void        construct( T* rawMemory ) const = 0 ;
  84.         } ;
  85.  
  86.         void                insertAtHead( ElemCtor const& ctor ) ;
  87.         //  ...
  88.     } ;
  89.  
  90. As a user, I might write:
  91.  
  92.     void
  93.     insertIntoList( ListOf< A >& list , int alpha , int beta )
  94.     {
  95.         class C : public ListOf< A >::ElemCtor
  96.         {
  97.         public :
  98.                                 C( int a , int b )
  99.                                     :   alpha( a )
  100.                                     ,   beta( b )
  101.                                 {}
  102.             virtual void        construct( T* rawMemory ) const
  103.             {
  104.                 new ( rawMemory ) A( alpha , beta ) ;
  105.             }
  106.         private :
  107.             int                 alpha ;
  108.             int                 beta ;
  109.         } ;
  110.         list.insertAtHead( C( alpha , beta ) ) ;
  111.     }
  112.  
  113. With member templates, this could be even easier, since you no longer
  114. need the base class ListOf< T >::ElemCtor, and you could pass global
  115. functions or functional objects indifferently.  Even using the above
  116. scheme, most of the derived classes can be simpler.  Typically, you
  117. might skip the constructor, make the data members public, declare a
  118. named local instance of the class, and share the data members, thus:
  119.  
  120.     void
  121.     insertIntoList( ListOf< A >& list , int alpha , int beta )
  122.     {
  123.         class C : public ListOf< A >::ElemCtor
  124.         {
  125.         public :
  126.             virtual void        construct( T* rawMemory ) const
  127.             {
  128.                 new ( rawMemory ) A( alpha , beta ) ;
  129.             }
  130.  
  131.             int                 alpha ;
  132.             int                 beta ;
  133.         }                   c ;
  134.         c.alpha = alpha ;
  135.         c.beta = beta ;
  136.         list.insertAtHead( c ) ;
  137.     }
  138.  
  139. If the constructor arguments are not just the arguments of the
  140. function, this is the classical way of simulating nested functions and
  141. closure.  A bit verbose, but still quite usable.
  142.  
  143. --
  144. James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
  145. GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
  146. Conseils, itudes et rialisations en logiciel orienti objet --
  147.                 -- A la recherche d'une activiti dans une region francophone
  148. ---
  149. [ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  150.   Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  151.   is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
  152.